package validate

import (
	"reflect"
	"strings"

	// 这个包是用于验证的
	"github.com/gin-gonic/gin/binding"
	// 这个包是用于中文翻译
	"github.com/go-playground/locales/zh"
	// 这个包是用于翻译错误信息的
	ut "github.com/go-playground/universal-translator"
	// 这个包是用于验证和翻译错误信息的
	"github.com/go-playground/validator/v10"
	// 这个包是用于中文翻译
	zh_translations "github.com/go-playground/validator/v10/translations/zh"
)

// trans 用于存储翻译器实例
var trans ut.Translator

// init 初始化翻译器和验证器
func init() {
	// 创建翻译器
	uni := ut.New(zh.New())
	trans, _ = uni.GetTranslator("zh")

	// 注册翻译器
	v, ok := binding.Validator.Engine().(*validator.Validate)
	if ok {
		_ = zh_translations.RegisterDefaultTranslations(v, trans)
	}

	// 注册标签名函数，用于自定义字段名
	v.RegisterTagNameFunc(func(field reflect.StructField) string {
		// 尝试获取标签中的label，如果没有则返回json标签名
		label := field.Tag.Get("label")
		if label != "" {
			return label
		}

		// 如果label为空，返回json标签的名字
		jsonTag := field.Tag.Get("json")
		if jsonTag != "" {
			// 如果json标签包含选项，只取第一个部分
			parts := strings.Split(jsonTag, ",")
			return parts[0]
		}

		// 如果都没有，则返回字段名
		return field.Name
	})
}

// ValidateResponse 验证错误的响应结构
type ValidateResponse struct {
	FieldMap map[string]any
	Msg      string
}

// ... existing code ...

// ValidateErr 处理验证错误并返回格式化的错误信息
// 参数:
//   - err: 验证错误信息
//
// 返回值:
//   - res: 包含字段映射和错误消息的ValidateResponse结构体
func ValidateErr(err error) (res ValidateResponse) {
	// 将传入的错误转换为验证错误类型
	errs, ok := err.(validator.ValidationErrors)
	if !ok {
		// 如果不是验证错误，直接返回原始错误信息
		res.Msg = err.Error()
		return
	}

	// 初始化用于存储字段错误信息的map和错误消息列表
	var m = map[string]any{}
	var list []string

	// 遍历所有验证错误
	for _, e := range errs {
		// 使用翻译器将错误信息翻译为中文
		msg := e.Translate(trans)

		// 尝试按"---"分隔符分割错误信息
		_list := strings.Split(msg, "---")

		if len(_list) >= 2 {
			// 如果能分割成两部分，第一部分是字段名，第二部分是错误信息
			m[_list[0]] = _list[1]
			list = append(list, _list[1])
		} else if len(_list) == 1 {
			// 如果只能分割成一部分，说明翻译格式不同
			// 使用字段名作为key而不是'field_'加数字
			fieldName := e.Field()
			m[fieldName] = _list[0]
			list = append(list, _list[0])
		}
	}

	// 设置返回结果
	res.FieldMap = m
	res.Msg = strings.Join(list, ";")
	return
}

// ... existing code ...
